package com.zxl.chatroomserver;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class ChatRoomClient implements Runnable {

    private Selector selector;
    private SocketChannel socketChannel;
    private volatile boolean stop;
    private String ipAddr;
    private int port;

    public ChatRoomClient(String ipAddr, int port) {
        System.out.println(" client starting ------ ");
        this.ipAddr = ipAddr;
        this.port = port;
        try {
            selector = Selector.open(); //创建多路复用器
            socketChannel = SocketChannel.open(); //创建socketChannel对象
            socketChannel.configureBlocking(false); //非阻塞
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

    }

    public void start() {
        //如果连接成功，就注册到selector上，发送请求，读取应答
        try {
            if (socketChannel.connect(new InetSocketAddress(ipAddr, port))) {
                System.out.println(" client connected success ! ");
                socketChannel.register(selector, SelectionKey.OP_READ);
                sendMsg(socketChannel);
            } else {
                socketChannel.register(selector, SelectionKey.OP_CONNECT);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        while (!stop) {
            try {
                selector.select(1000);
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> it = selectedKeys.iterator();
                SelectionKey key = null;

                while (it.hasNext()) {
                    key = it.next();
                    it.remove();
                    try {
                        handleInput(key);
                    } catch (Exception e) {
                        if (key != null) {
                            key.cancel();
                            if (key.channel() != null) {
                                key.channel().close();
                            }
                        }
                    }
                }


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void handleInput(SelectionKey key) throws IOException {
        SocketChannel sc = (SocketChannel) key.channel();
        if (key.isConnectable()) {
            if (sc.finishConnect()) {
                sc.register(selector, SelectionKey.OP_READ);
                sendMsg(sc);
            } else {
                System.exit(1); // 连接失败，退出
            }
        }

        if (key.isReadable()) {
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            int readSize = sc.read(readBuffer);
            if (readSize > 0) {
                readBuffer.flip();
                byte[] bytes = new byte[readBuffer.remaining()];
                readBuffer.get(bytes);
                String body = new String(bytes, "UTF-8");
                System.out.println("client接收到消息：" + body);
                sendMsg(sc);
            } else if (readSize < 0) {
                //关闭链路
                key.cancel();
                sc.close();
            } else {
            }

        }

    }

    private void sendMsg(SocketChannel sc) throws IOException {
        byte[] req = "hi, i am client !".getBytes();
        ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
        writeBuffer.put(req);
        writeBuffer.flip();
        sc.write(writeBuffer);
        //判断缓冲区是否写入完成
        if (!writeBuffer.hasRemaining()) {
            System.out.println("客户端消息发送完成 ！！！");
        }

    }


    @Override
    public void run() {
        start();
    }
}
